package cc.telecomdigital.tdstock.Tools;

import java.util.ArrayList;
import java.util.List;

import cc.telecomdigital.tdstock.Framework.UniqueItem.TDStockLog;

import android.app.Activity;
import android.content.Intent;

public abstract class Abstract_ActivityController
{
	/** Global use to kill Activity after switch **/
	/** Allow easier for debug **/
	static private boolean	finishRequired	= false;
	//RealtimeStockActivity  is current activity
	public static boolean IsCurrentActivity=false;
	
	public enum CHANGE_DIRECTION
	{
		BACK, NEXT
	};

	//Lock the list on accessing
	protected Object listLock  = new Object();
	
	
     protected List<Class<? extends Activity>>	activityClassList;
	protected int							indexOfCurActivity;
	static    protected boolean				debugMode	= false;

	final protected String					LOG_TAG;

	public boolean IsDestroyOnFinish()
	{
		return finishRequired;
	}
		
	/** Create the module Identity Title **/
	protected abstract String GetModuleIdentity();

	/** Internal Switching mechanism, should be blind to upper layer of developer **/
	protected abstract void ActivitySwitchPerform(Activity iCallActivity,
			Class<? extends Activity> iChangingActClass, Intent iIntentObj,
			CHANGE_DIRECTION iSwitchDir);

	public void ActivityReEnforce(Activity iCallActivity, Class<? extends Activity> iChangingActClass, Intent iIntentObj)
	{
		if (iCallActivity.getClass().equals(iChangingActClass))
			return;
		
		ActivitySwitchPerform(iCallActivity, iChangingActClass, iIntentObj, CHANGE_DIRECTION.NEXT);		
	}
	
	/** Set Debug Mode to see more descriptive result **/
	public void SetDebugMode(boolean iEnable)
	{		
		debugMode = iEnable;
	}

	/** Owner could be anything, activity, Context **/
	protected Abstract_ActivityController()
	{
		activityClassList = new ArrayList<Class<? extends Activity>>();
		indexOfCurActivity = -1;
		LOG_TAG = GetModuleIdentity();
	}

	/** Transfer ownership **/
	public Abstract_ActivityController(Abstract_ActivityController iImport)
	{
		activityClassList = new ArrayList<Class<? extends Activity>>();
		activityClassList.addAll(iImport.activityClassList);

		indexOfCurActivity = iImport.indexOfCurActivity;
		LOG_TAG = iImport.GetModuleIdentity();
	}

	/** Once it is call destroy is not usable anymore **/
	public void DestoryController()
	{
		if (activityClassList != null)
		{
			ActivityClearList();
			activityClassList = null;

			TDStockLog.i(LOG_TAG,"Object is destoryed, and cannot be reused.");
		}
	}

	/** Is the list empty **/
	public boolean IsActivityListEmpty()
	{
		return activityClassList.isEmpty();
	}

	/** Check the existence of the activity in the list **/	
	public Class<? extends Activity> GetActivityClassOf(int iPos)
	{
		if (iPos >= activityClassList.size())
			return null;

		return activityClassList.get(iPos);
	}

	/** Find the location of the object in the class **/
	public int GetClassPosition(Class<? extends Activity> iClassObj)
	{
		synchronized(listLock)
		{
			if (activityClassList.size() == 0)
				return -1;
			
			return activityClassList.indexOf(iClassObj);
		}
	}
	
	/** Report the Current Focus of Activity **/
	public Class<? extends Activity> GetCurrentActivityClass()
	{
		if ((activityClassList.size() == 0) || (indexOfCurActivity == -1))
			return null;

		return activityClassList.get(indexOfCurActivity);
	}

	/** Get the index of the Current Class in the list
	 *  It tells how many Activity was being opened in the front
	 * @return
	 */
	public int GetCurrentClassIndex()
	{
		return indexOfCurActivity;
	}
	
	/** Remove some class after the index.
	 * Be caution, using this, could manipulate the sequence of order (when going backward)
	 * @param iIndex
	 * @return
	 */
	public boolean RemoveClassAfter(int iIndex)
	{
		int size;
//		int startIndex;
		
		if (iIndex == -1)
			return false;

		synchronized(listLock)
		{
			size = activityClassList.size();
			if (size == 0)
				return false;
			
			//Try to auto fix the value
			if (iIndex >= size)
				iIndex = size-2;
			
			activityClassList = activityClassList.subList(0, iIndex+1);
						
//			++iIndex;
//			size = activityClassList.size();
//			if (size == 0)
//				return false;						
			
//			for (startIndex = iIndex; startIndex < size; startIndex++)
//				activityClassList.remove(iIndex);
		}
		
		if (indexOfCurActivity >= iIndex)
			indexOfCurActivity = activityClassList.size()-1;
		
		return true;		
	}
	
	public boolean RemoveClassAfter(Class<? extends Activity> iClassObj)
	{
		int index;
		
		synchronized(listLock)
		{			
			if (activityClassList.size() == 0)
				return false;
						
			index = activityClassList.indexOf(iClassObj);			
		}
		return RemoveClassAfter(index);
	}
	
	/** Get the count in the list **/
	public int GetListCount()
	{
		return activityClassList.size();
	}
		
	/** Import for intentObj for switch, object will be use **/
	public boolean ActivityForwardSwitch(Activity iCallActivity,
			Class<? extends Activity> iToActivityClass, Intent intentObj)
	{
		if (debugMode)
			TDStockLog.i(LOG_TAG, "ActivityForwardSwitch Entered");
		
		synchronized (listLock)
		{
			int pos;

			if (indexOfCurActivity != -1)
			{
				if (activityClassList.get(indexOfCurActivity).equals(
						iToActivityClass))
					return false;
			}

			// If the To is already exist, we will remove the after
			pos = activityClassList.indexOf(iToActivityClass);
			if (pos != -1)
			{
				if (pos == 0)
				{
					activityClassList.clear();
					indexOfCurActivity = 0;
				}
				else
				{
					activityClassList = activityClassList.subList(0, pos);
					indexOfCurActivity = pos-1;	
				}
				
				if (debugMode)
					TDStockLog.i(LOG_TAG, "Activitly has been revised.");
			}
			else
			{
				if (debugMode)
					TDStockLog.i(LOG_TAG,
							"Introduced a new Activity to list.");
			}

			ActivitySwitchPerform(iCallActivity, iToActivityClass, intentObj,
							  CHANGE_DIRECTION.NEXT);

			activityClassList.add(iToActivityClass);			
			indexOfCurActivity = activityClassList.size() - 1;
			return true;
		}
	}

	/** This would just go back to the previous list selection **/
	public boolean ActivityBackwardSwitch(Activity iCallActivity)
	{
		Intent intentObj;
		
		intentObj = new Intent();
		return ActivityBackwardSwitch(iCallActivity, intentObj);
	}

	/** This would just go back to the previous list selection, the intent
	   source and destination will be modified **/
	public boolean ActivityBackwardSwitch(Activity iCallActivity, Intent iIntentObj)
	{
		synchronized (listLock)
		{
			Class<? extends Activity> toActivityClass;

			// We are at the root, nothing we can change
			if (indexOfCurActivity <= 0)
			{
				//Clean self
				ActivityClearList();
				return false;
			}

			// Get Activity and shorten the list
			toActivityClass = activityClassList.get(indexOfCurActivity - 1);

			ActivitySwitchPerform(iCallActivity, toActivityClass, iIntentObj,
					            CHANGE_DIRECTION.BACK);
			activityClassList = activityClassList.subList(0,
					indexOfCurActivity);
			indexOfCurActivity = activityClassList.size() - 1;
			return true;
		}
	}

	/** Switch the activity to the top of the list
	 * @param iCallActivity - caller activity
	 * @return
	 */
	public boolean ActivitySwitchToTheTop(Activity iCallActivity)
	{
		return ActivitySwitchToTheTop(iCallActivity, new Intent()); 
	}
	
	/** Switch the activity to the top of the list
	 * @param iCallActivity - Caller Activity
	 * @param iIntentObj    - switch Activity receive message
	 * @return
	 */
	public boolean ActivitySwitchToTheTop(Activity iCallActivity, Intent iIntentObj)
	{
		synchronized(listLock)
		{
			Class<? extends Activity> toActivityClass;
			
			if ((activityClassList == null) || (activityClassList.size() == 0))
				return false;
			
			toActivityClass = activityClassList.get(0);
			if (toActivityClass.equals(iCallActivity.getClass()))
				return false;
			
			// If the To is already exist, we will remove the after
			if (debugMode)
				TDStockLog.i(LOG_TAG, "Going Back to Home");

			ActivitySwitchPerform( iCallActivity, toActivityClass, iIntentObj,
							   CHANGE_DIRECTION.BACK);
			activityClassList.clear();
			activityClassList.add(toActivityClass);
			indexOfCurActivity = 0;
			return true;				
		}
	}
	
	/** Enforce a backward UI switching, even it was not in the list, it will be put into
	    the top list, since you have violated the theory **/	
	public boolean ActivityBackwardSwitchToTop(Activity iCallActivity,
			Class<? extends Activity> iToActivityClass, Intent iIntentObj)
	{
		synchronized (listLock)
		{
			if (indexOfCurActivity != -1)
			{
				if (activityClassList.get(indexOfCurActivity).equals(
						iToActivityClass))
					return false;
			}

			// If the To is already exist, we will remove the after
			if (debugMode)
				TDStockLog.i(LOG_TAG, "Introduced a new Activity to list.");

			ActivitySwitchPerform( iCallActivity, iToActivityClass, iIntentObj,
							   CHANGE_DIRECTION.BACK);
			activityClassList.clear();
			activityClassList.add(iToActivityClass);
			indexOfCurActivity = 0;
			return true;
		}		
	}
	
	/** Clear the Activity List, it is not intended to be used by the upper layer **/
	public void ActivityClearList()
	{
		synchronized (listLock)
		{
			activityClassList.clear();
			indexOfCurActivity = -1;
		}
	}

	/** Clear the Activity List and set self to be the top **/
	public void ActivityResetToTop(Class<? extends Activity> iActivityClass)
	{
		synchronized (listLock)
		{
			activityClassList.clear();
			activityClassList.add(iActivityClass);
			indexOfCurActivity = 0;
		}
	}
		
	/** Remove an existing Activity from the list **/
	public boolean ActivityRemoveFromList(Class<? extends Activity> iActivityClass)
	{
		synchronized(listLock)
		{
			int     index;
			
			//was not existed
			index = activityClassList.indexOf(iActivityClass);
			if (index == -1)
				return false;
			
			//If it is the same class, then we should not allow
			if (indexOfCurActivity != -1)
			{
				if (activityClassList.get(indexOfCurActivity).equals(iActivityClass))
					return false;
			}

			// If the To is already exist, we will remove the after
			if (debugMode)
				TDStockLog.i(LOG_TAG, "RemoveActivityFromList: " + iActivityClass);

			//Think about how to modify the index			
			//Can not be equaled
			if (index < indexOfCurActivity)
				--indexOfCurActivity;
								
			activityClassList.remove(index);
			return true;
		}
	}
	
	
	/** This would make a jump from the curAcitivity to your destinated one.
	    The direction and saving is determined based on information at the list. **/
	public boolean ActivityFreeSwitch(Activity iCallActivity,
			Class<? extends Activity> iToActivityClass, Intent iIntentObj)
	{
		//更改使当前UI为RealtimeStockActivity
		//hunter 2011-10-26
		//当不是用框架跳转时 indexOfCurActivity值不会被更改，必须手动更改
		if(IsCurrentActivity)
		{
			indexOfCurActivity=0;
			IsCurrentActivity=false;
		}
		synchronized (listLock)
		{
			int srcPos, desPos;
			CHANGE_DIRECTION switchDir;
			TDStockLog.d("test", "indexOfCurActivity"+(indexOfCurActivity != -1)+"");
			if (indexOfCurActivity != -1)
			{
				TDStockLog.d("test", activityClassList.get(indexOfCurActivity)+"");
				if (activityClassList.get(indexOfCurActivity).equals(
						iToActivityClass))
					return false;
			}

			srcPos = indexOfCurActivity;
			desPos = activityClassList.indexOf(iToActivityClass);
			// if it does not exist, it is a new
			if (desPos == -1)
			{
				switchDir = CHANGE_DIRECTION.NEXT;
				// Consider as an add in from the srcPos;
				// Now we shall be change our list;
				activityClassList = activityClassList
						.subList(0, srcPos + 1);
			}
			else if (desPos < srcPos)
			{
				switchDir = CHANGE_DIRECTION.BACK;
				// Clear at the destPos;
				if (desPos == 0)
					activityClassList.clear();
				else
					activityClassList = activityClassList.subList(0, desPos);
			}
			else
			{
				// There is no possibility to be equal
				// This would be a big jump, usually not exist
				switchDir = CHANGE_DIRECTION.NEXT;
				activityClassList = activityClassList.subList(0, srcPos);
			}

			ActivitySwitchPerform(iCallActivity, iToActivityClass, iIntentObj,
					switchDir);

			activityClassList.add(iToActivityClass);
			indexOfCurActivity = activityClassList.size() - 1;
			return true;
		}
	}
}
